// CHAPTER 5 OF OBJECT ORIENTED JAVASCRIPT
// PROTOTYPE
mainchapter("5 PROTOTYPE");

(function(){
	// 5.1 ADDING METHODS AND PROPERTIES USING PROTOTYPE
	chapter("5.1 ADDING METHODS AND PROPERTIES USING PROTOTYPE");
	try{
		function Gadget(name, color){
			this.name = name;
			this.color = color;
			this.whatAreYou = function(){
				return this.name+": "+this.color;
			}
		}
		Gadget.prototype.price = 100;
		Gadget.prototype.rating = 3;
		Gadget.prototype.getInfo = function(){
			return this.rating+": "+this.price;
		}
		var newtoy = new Gadget('webcam','black');
		assertEquals(newtoy.name,"webcam");
		assertEquals(newtoy.color,"black");
		assertEquals(newtoy.whatAreYou(),"webcam: black");
		assertEquals(newtoy.price,100);
		assertEquals(newtoy.rating,3);
		success("5.1a Using prototype properties");
		assertEquals(newtoy.getInfo(),"3: 100");
		Gadget.prototype.getInfo = function(){
			return Gadget.prototype.rating+": "+Gadget.prototype.price;
		}
		assertEquals(newtoy.getInfo(),"3: 100");
		success("5.1b Using prototype methods");
		Gadget.prototype.name = 'foo';
		assertEquals(newtoy.name,"webcam");
		delete newtoy.name;
		assertEquals(newtoy.name,"foo");
		newtoy.name="camera";
		assertEquals(newtoy.name,"camera");
		success("5.1c Overwriting prototype's property");
	}catch(e){
		$ERROR("5.1 ADDING METHODS AND PROPERTIES USING PROTOTYPE : "+e.message);
	}
})();


(function(){
	// 5.2 HasOwnProperty
	chapter("5.2 Objects and PropertyMethods");
	try{
		function Gadget(name, color){
			this.name = name;
			this.color = color;
			this.whatAreYou = function(){
				return this.name+": "+this.color;
			}
		}
		Gadget.prototype.price = 100;
		Gadget.prototype.rating = 3;
		Gadget.prototype.getInfo = function(){
			return this.rating+": "+this.price;
		}
		var newtoy = new Gadget('webcam','black');
		assertEquals(newtoy.hasOwnProperty('name'),true);
		assertEquals(newtoy.hasOwnProperty('price'),false);
		success("5.2a object.hasOwnProperty( prop )");
		assertEquals(newtoy.propertyIsEnumerable('name'),true);
		assertEquals(newtoy.propertyIsEnumerable('constructor'),false);
		assertEquals(newtoy.propertyIsEnumerable('price'),false);
		assertEquals(newtoy.constructor.prototype.propertyIsEnumerable('price'),true);
		success("5.2b object.propertyIsEnumerable( prop )");
	}catch(e){
		$ERROR("5.2 a/b Objects and PropertyMethods : "+e.message);
	}
	try{
		var monkey = {
			hair: true,
			feeds: 'bananas',
			breathes: 'air'
		};
		function Human(name){
			this.name = name;
		}
		Human.prototype = monkey;
		var george = new Human('George');
		assertEquals(monkey.isPrototypeOf(george),true);
		assertEquals(george.isPrototypeOf(monkey),false);
		success("5.2c object.isPrototypeOf");
	}catch(e){
		$ERROR("5.2 Objects and PropertyMethods : "+e.message);
	}
})();


(function(){
	// 5.3 SOME PROTOTYPE GOTCHAS
	chapter("5.3 SOME PROTOTYPE GOTCHAS");
	try{
		function Dog(){this.tail = true;}
		var benji = new Dog();
		var rusty = new Dog();
		Dog.prototype.say = function(){return 'Woof!';}
		assertEquals(benji.say(),'Woof!');
		assertEquals(rusty.say(),'Woof!');
		assertEquals(typeof benji.say,"function");
		assertEquals(typeof benji.constructor.prototype.say,"function");
		assertEquals(rusty.constructor,benji.constructor.prototype.constructor);
		assertEquals(typeof benji.constructor.prototype.tail, "undefined");
		success("5.3a object.constructor.prototype");
		Dog.prototype = {paws : 4, hair: true};
		assertEquals(typeof benji.paws, "undefined");
		var lucy = new Dog();
		assertEquals(typeof benji.say,"function");
		assertEquals(typeof lucy.say,"undefined");
		assertEquals(lucy.paws,4);
		success("5.3b overwriting prototype");
	}catch(e){
		$ERROR("5.3 SOME PROTOTYPE GOTCHAS : "+e.message);
	}
})();





